"""
用户搜索记录接口测试
测试用户搜索记录的添加和查询功能
"""

import requests
import json
import time

base_url = "http://localhost:8080/api"
search_history_url = f"{base_url}/search-history"
users_url = f"{base_url}/users"


def login_user(username, password):
    """用户登录并返回token"""
    login_data = {"username": username, "password": password}
    response = requests.post(
        f"{users_url}/login",
        json=login_data,
        headers={"Content-Type": "application/json"},
    )
    if response.status_code == 200:
        return response.json().get("token")
    else:
        print(f"登录失败: {response.json()}")
        return None


def register_user(username, password):
    """用户注册"""
    register_data = {"username": username, "password": password}
    response = requests.post(
        f"{users_url}/register",
        json=register_data,
        headers={"Content-Type": "application/json"},
    )
    return response.status_code == 200


def test_search_history_info():
    """测试获取搜索记录管理接口信息"""
    print("=== 测试获取搜索记录管理接口信息 ===")

    try:
        response = requests.get(f"{search_history_url}/")

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 获取搜索记录接口信息成功")
            return True
        else:
            print("❌ 获取搜索记录接口信息失败")
            return False

    except Exception as e:
        print(f"❌ 获取搜索记录接口信息请求异常: {e}")
        return False


def test_add_search_history(token, search_query="Python编程"):
    """测试添加搜索记录"""
    print(f"\n=== 测试添加搜索记录 (search_query: {search_query}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    data = {"search_query": search_query}

    try:
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 添加搜索记录成功")
            return True
        else:
            print("❌ 添加搜索记录失败")
            return False

    except Exception as e:
        print(f"❌ 添加搜索记录请求异常: {e}")
        return False


def test_add_duplicate_search_history(token, search_query="Python编程"):
    """测试添加重复搜索记录（应该更新时间）"""
    print(f"\n=== 测试添加重复搜索记录 (search_query: {search_query}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    data = {"search_query": search_query}

    try:
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )

        print(f"状态码: {response.status_code}")
        print(f"响应内容: {json.dumps(response.json(), ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 重复搜索记录处理成功（更新时间）")
            return True
        else:
            print("❌ 重复搜索记录处理失败")
            return False

    except Exception as e:
        print(f"❌ 重复搜索记录测试请求异常: {e}")
        return False


def test_get_search_history_list(token, page=1, limit=10):
    """测试分页获取搜索记录"""
    print(f"\n=== 测试分页获取搜索记录 (page: {page}, limit: {limit}) ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.get(
            f"{search_history_url}/list?page={page}&limit={limit}", headers=headers
        )

        print(f"状态码: {response.status_code}")
        response_data = response.json()
        print(f"响应内容: {json.dumps(response_data, ensure_ascii=False, indent=2)}")

        if response.status_code == 200:
            print("✅ 获取搜索记录列表成功")
            print(f"总搜索记录数: {response_data.get('total', 0)}")
            print(
                f"当前页记录数量: {len(response_data.get('search_history_list', []))}"
            )
            return response_data
        else:
            print("❌ 获取搜索记录列表失败")
            return False

    except Exception as e:
        print(f"❌ 获取搜索记录列表请求异常: {e}")
        return False


def test_unauthorized_access():
    """测试未授权访问"""
    print("\n=== 测试未授权访问 ===")

    try:
        # 测试没有token的添加
        data = {"search_query": "Python编程"}
        headers = {"Content-Type": "application/json"}
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )
        print(f"无token添加搜索记录 - 状态码: {response.status_code}")

        # 测试没有token的查询
        response = requests.get(f"{search_history_url}/list", headers=headers)
        print(f"无token查询搜索记录 - 状态码: {response.status_code}")

        # 测试无效token
        headers = {
            "Authorization": "Bearer invalid_token",
            "Content-Type": "application/json",
        }
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )
        print(f"无效token添加搜索记录 - 状态码: {response.status_code}")

        if response.status_code == 401:
            print("✅ 未授权访问验证成功")
            return True
        else:
            print("❌ 未授权访问验证失败")
            return False

    except Exception as e:
        print(f"❌ 未授权访问测试异常: {e}")
        return False


def test_invalid_parameters(token):
    """测试无效参数"""
    print("\n=== 测试无效参数 ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }

    try:
        # 测试缺少search_query
        data = {}
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )
        print(f"缺少search_query - 状态码: {response.status_code}")

        # 测试空搜索关键词
        data = {"search_query": ""}
        response = requests.post(
            f"{search_history_url}/add", json=data, headers=headers
        )
        print(f"空搜索关键词 - 状态码: {response.status_code}")

        # 测试无效分页参数
        response = requests.get(
            f"{search_history_url}/list?page=0&limit=100", headers=headers
        )
        print(f"无效分页参数 - 状态码: {response.status_code}")

        if response.status_code == 422:  # FastAPI参数验证错误
            print("✅ 无效参数验证成功")
            return True
        else:
            print("❌ 无效参数验证失败")
            return False

    except Exception as e:
        print(f"❌ 无效参数测试异常: {e}")
        return False


def test_search_query_variations(token):
    """测试不同类型的搜索关键词"""
    print("\n=== 测试不同类型的搜索关键词 ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    # 不同类型的搜索关键词
    search_queries = [
        "Python编程",
        "Java教程",
        "数据结构与算法",
        "机器学习入门",
        "Web开发",
        "数据库设计",
        "人工智能",
        "前端框架Vue.js",
        "后端开发Spring Boot",
        "微服务架构",
    ]

    success_count = 0

    for query in search_queries:
        print(f"\n测试搜索关键词: {query}")
        if test_add_search_history(token, query):
            success_count += 1

    print(f"✅ 搜索关键词变化测试完成，成功: {success_count}/{len(search_queries)}")
    return success_count == len(search_queries)


def test_pagination_functionality(token):
    """测试分页功能"""
    print("\n=== 测试分页功能 ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    # 先获取总记录数
    first_page = test_get_search_history_list(token, page=1, limit=5)
    if not first_page:
        print("❌ 无法获取第一页数据")
        return False

    total = first_page.get("total", 0)
    print(f"总记录数: {total}")

    if total > 5:
        # 测试第二页
        print("\n测试第二页数据:")
        second_page = test_get_search_history_list(token, page=2, limit=5)

        if second_page:
            print("✅ 分页功能测试成功")
            return True
        else:
            print("❌ 分页功能测试失败")
            return False
    else:
        print("✅ 数据不足以测试分页，但基本功能正常")
        return True


def test_search_history_order(token):
    """测试搜索记录排序"""
    print("\n=== 测试搜索记录排序 ===")

    if not token:
        print("❌ 没有有效的token，跳过测试")
        return False

    # 添加几个带时间间隔的搜索记录
    test_queries = ["排序测试1", "排序测试2", "排序测试3"]

    for i, query in enumerate(test_queries):
        print(f"添加搜索记录 {i+1}: {query}")
        test_add_search_history(token, query)

    # 获取搜索记录列表
    result = test_get_search_history_list(token, page=1, limit=10)

    if result and result.get("search_history_list"):
        search_list = result["search_history_list"]
        print(f"获取到 {len(search_list)} 条搜索记录")

        # 检查是否按更新时间降序排列
        timestamps = [record["updated_at"] for record in search_list]
        is_descending = all(
            timestamps[i] >= timestamps[i + 1] for i in range(len(timestamps) - 1)
        )

        if is_descending:
            print("✅ 搜索记录按时间降序排列正确")
            return True
        else:
            print("❌ 搜索记录排序不正确")
            return False
    else:
        print("❌ 无法获取搜索记录进行排序测试")
        return False


def test_multiple_users_search_history():
    """测试多个用户的搜索记录隔离"""
    print("\n=== 测试多用户搜索记录隔离 ===")

    # 创建两个测试用户
    timestamp = int(time.time())
    user1_name = f"search_test_user1_{timestamp}"
    user2_name = f"search_test_user2_{timestamp}"
    password = "123456"

    # 注册用户
    if not register_user(user1_name, password):
        print("❌ 用户1注册失败")
        return False

    if not register_user(user2_name, password):
        print("❌ 用户2注册失败")
        return False

    # 登录用户
    token1 = login_user(user1_name, password)
    token2 = login_user(user2_name, password)

    if not token1 or not token2:
        print("❌ 用户登录失败")
        return False

    # 用户1添加搜索记录
    print("\n用户1添加搜索记录:")
    test_add_search_history(token1, "用户1的搜索")

    # 用户2添加搜索记录
    print("\n用户2添加搜索记录:")
    test_add_search_history(token2, "用户2的搜索")

    # 检查用户1只能看到自己的搜索记录
    print("\n用户1查看搜索记录:")
    user1_result = test_get_search_history_list(token1)

    # 检查用户2只能看到自己的搜索记录
    print("\n用户2查看搜索记录:")
    user2_result = test_get_search_history_list(token2)

    if user1_result and user2_result:
        user1_queries = [
            record["search_query"]
            for record in user1_result.get("search_history_list", [])
        ]
        user2_queries = [
            record["search_query"]
            for record in user2_result.get("search_history_list", [])
        ]

        # 检查用户1不能看到用户2的搜索记录
        if "用户2的搜索" not in user1_queries and "用户1的搜索" not in user2_queries:
            print("✅ 多用户搜索记录隔离测试成功")
            return True
        else:
            print("❌ 多用户搜索记录隔离失败")
            return False
    else:
        print("❌ 无法获取用户搜索记录")
        return False


def run_all_search_history_tests():
    """运行所有搜索记录功能测试"""
    print("开始用户搜索记录功能测试...")
    print("=" * 80)

    # 测试用户名（使用时间戳确保唯一性）
    username = f"search_history_test_user_{int(time.time())}"
    password = "123456"

    # 1. 注册测试用户
    print(f"注册测试用户: {username}")
    if not register_user(username, password):
        print("❌ 用户注册失败，测试终止")
        return

    # 2. 登录获取token
    print(f"登录测试用户: {username}")
    token = login_user(username, password)
    if not token:
        print("❌ 用户登录失败，测试终止")
        return

    print(f"✅ 获得token: {token[:20]}...")

    # 3. 测试获取搜索记录接口信息
    test_search_history_info()

    # 4. 测试未授权访问
    test_unauthorized_access()

    # 5. 测试无效参数
    test_invalid_parameters(token)

    # 7. 测试添加搜索记录
    test_add_search_history(token, "Python编程")
    test_add_search_history(token, "Java教程")
    test_add_search_history(token, "数据结构")

    # 8. 测试重复搜索记录
    test_add_duplicate_search_history(token, "Python编程")

    # 9. 测试获取搜索记录列表
    test_get_search_history_list(token)

    # 10. 测试不同类型的搜索关键词
    test_search_query_variations(token)

    # 11. 测试分页功能
    test_pagination_functionality(token)

    # 12. 测试搜索记录排序
    test_search_history_order(token)

    # 13. 测试多用户搜索记录隔离
    test_multiple_users_search_history()

    # 14. 最终状态验证
    print(f"\n=== 验证最终搜索记录状态 ===")
    final_result = test_get_search_history_list(token)
    if final_result:
        print(f"最终搜索记录总数: {final_result.get('total', 0)}")

    print("\n" + "=" * 80)
    print("用户搜索记录功能测试完成")


if __name__ == "__main__":
    run_all_search_history_tests()
